#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <openssl/aes.h>
#include <limits.h> // 包含PATH_MAX常量
#include <dirent.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>


#if defined(WIN32) || defined(WIN64)
#include "windows.h"
#endif

#include "define.h"
#include "common.h"
#include "zlog.h"
#include "JsonParser.h"

Snowflake sf;
char g_ServerIp[64] = { 0 };
char g_ServerPort[64] = { 0 };
extern sqlite3 *g_sqlite3_db;

//休眠请求
extern int dormancyRequest;
// 定义互斥锁
pthread_mutex_t file_mutex = PTHREAD_MUTEX_INITIALIZER;

void timeSleep(int ms)
{
#if defined(WIN32) || defined(WIN64)
	Sleep(ms);
#else
	usleep(ms * 1000);
#endif
}

/**
 * @description: 查看文件夹是否存在不存在创建
 * @param {char} *path
 * @return {*}
 */
int checkAndCreateDirectory(const char *path)
{
	struct stat st;
	int result = stat(path, &st);
	if (result == 0)
	{
		if (S_ISDIR(st.st_mode))
		{
			// 文件夹已存在
			return 1;
		}
		else
		{
			// 路径已存在但不是文件夹
			return 0;
		}
	}
	else
	{
		// 文件夹不存在，尝试创建文件夹
		result = mkdir(path, 0777); // 设置权限为777，可根据需求进行修改
		if (result == 0)
		{
			// 创建文件夹成功
			return 1;
		}
		else
		{
			// 创建文件夹失败
			int error = errno;
			dzlog_error("create directory error %s", strerror(errno));
			return 0;
		}
	}
}
/**
 * @description: md5文件计算
 * @param {char} *file_path
 * @param {char} *md5_hash
 * @return {*}
 */
void calculate_md5(const char *file_path, char *md5_hash)
{
	FILE *file = fopen(file_path, "rb");
	if (file == NULL)
	{
		dzlog_error("Failed to open file calculate_md5 file_path:%s\n", file_path);
		return;
	}

	MD5_CTX md5_context;
	MD5_Init(&md5_context);

	unsigned char buffer[1024];
	int bytes;

	while ((bytes = fread(buffer, 1, sizeof(buffer), file)) != 0)
	{
		MD5_Update(&md5_context, buffer, bytes);
	}

	unsigned char tmp[100];

	MD5_Final(tmp, &md5_context);
	int i = 0;
	for (i = 0; i < MD5_DIGEST_LENGTH; i++)
	{
		sprintf(md5_hash + (i * 2), "%02x", tmp[i]);
	}
	md5_hash[MD5_DIGEST_LENGTH * 2] = '\0';
	fclose(file);
}

/**
 * @description: 文件sha256
 * @param {char} *filename
 * @param {unsigned char} *hash
 * @return {*}
 */
void calculate_file_sha256(const char *filename, char *hash_hex)
{
	FILE *file;
	SHA256_CTX sha256_ctx;
	unsigned char buffer[BUFFER_SIZE];
	size_t bytes_read;

	// 打开文件以进行读取操作
	file = fopen(filename, "rb");
	if (file == NULL)
	{
		printf("Failed to open the file.\n");
		return;
	}

	// 初始化 SHA-256 上下文
	if (!SHA256_Init(&sha256_ctx))
	{
		printf("Failed to initialize SHA-256 context.\n");
		fclose(file);
		return;
	}

	// 逐步读取文件内容并更新 SHA-256 哈希值
	while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0)
	{
		if (!SHA256_Update(&sha256_ctx, buffer, bytes_read))
		{
			printf("Failed to update SHA-256 context.\n");
			fclose(file);
			return;
		}
	}

	// 完成哈希计算并获取最终的 SHA-256 哈希值
	unsigned char hash[SHA256_DIGEST_LENGTH];
	if (!SHA256_Final(hash, &sha256_ctx))
	{
		printf("Failed to finalize SHA-256 context.\n");
		fclose(file);
		return;
	}

	// 关闭文件
	fclose(file);

	// 将哈希值转换为十六进制字符串
	int i = 0;
	i = 0;
	while (i < SHA256_DIGEST_LENGTH)
	{
		sprintf(&hash_hex[i * 2], "%02x", hash[i]);
		i++;
	}
}

/**
 * @description: 文件大小计算
 * @param {char} *file_path
 * @return {*}
 */
long calculate_file_size(const char *file_path)
{
	FILE *file = fopen(file_path, "rb");
	if (file == NULL)
	{
		dzlog_error("Failed to open file.file_path:%s\n", file_path);
		return -1; // 返回错误代码
	}

	fseek(file, 0, SEEK_END);	  // 将文件指针定位到文件末尾
	long file_size = ftell(file); // 获取文件指针的当前位置，即文件大小

	fclose(file);
	return file_size;
}

unsigned int getstimeval()
{
	unsigned int us;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	us = (int)(tv.tv_usec);
	return us;
}

void GF_GetGUID(char* uuid) {
	// 16 字节的 UUID 数据
	unsigned char data[16];

	// 使用当前时间初始化随机种子
	srand((unsigned int)time(NULL) + rand());

	// 生成 16 个随机字节
	for (int i = 0; i < 16; ++i) {
		data[i] = (unsigned char)(rand() % 256);
	}

	// 设置版本：第 7 字节高 4 位为 0100 (0x40)
	data[6] = (data[6] & 0x0F) | 0x40;

	// 设置变体：第 9 字节高 2 位为 10 (0x80)
	data[8] = (data[8] & 0x3F) | 0x80;

	// 格式化为 UUID 字符串 (8-4-4-4-12)
	snprintf(uuid, 37, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
		data[0], data[1], data[2], data[3],
		data[4], data[5],
		data[6], data[7],
		data[8], data[9],
		data[10], data[11], data[12], data[13], data[14], data[15]);

	return;
}

#define AES_BITS 128

static unsigned char char_to_i(char ch)
{
	unsigned char byte = 0;
	if (ch >= 'A' && ch <= 'F')
	{
		byte = 10 + (ch - 'A');
	}
	else if (ch >= 'a' && ch <= 'f')
	{
		byte = 10 + (ch - 'a');
	}
	else
		byte = ch - '0';

	return byte;
}

static unsigned char hex_to_byte(char b1, char b2)
{
	unsigned char byte1 = char_to_i(b1);
	unsigned char byte2 = char_to_i(b2);

	return (byte1 * 16 + byte2);
}

char *string_to_hex(const char *str, int *outlen)
{
	int len = strlen(str);
	if ((len % 2) != 0)
	{
		dzlog_error("cmd:[SYSTEM], msg:[string_to_hex, string length not  2*N ");
		return NULL;
	}

	int bytelen = len / 2;
	char *out = malloc(bytelen);
	int i = 0, offset = 0;
	while (i < len)
	{
		char ch1 = str[i];
		char ch2 = str[i + 1];
		out[offset] = hex_to_byte(ch1, ch2);
		i += 2;
		offset++;
	}

	(*outlen) = bytelen;
	return out;
}

/**
 * @brief 查询字典表
 *
 * @param key 查询key
 * @param value 传入字符串数组
 * @param parentid 查询父节点
 * @return int 成功返回1失败返回0
 */
int sql_dict(const char *key, char *value, const char parentid)
{
	char *sql[1024] = {0};
	char *err_msg = NULL;

	sprintf(sql, "select value from dict_item where key = %s and parentid = %s", key, parentid);
	if (sqlite3_exec(g_sqlite3_db, sql, dict_callback, value, &err_msg) != SQLITE_OK)
	{
		dzlog_error("查询失败，查找不到key = %s,parentid = %s,error=%s", key, parentid, sqlite3_errmsg(g_sqlite3_db));
		sqlite3_free(err_msg);
		return 0;
	}
	return 1;
}

/// @brief 非递归查找文件第一个匹配文件名
/// @param directory
/// @param keyword
/// @return
char *search_directory_firstone(const char *directory, const char *keyword)
{
	DIR *dir = opendir(directory);
	if (dir == NULL)
	{
		dzlog_error(stderr, "无法打开目录 %s\n", directory);
		return NULL;
	}

	char *match = NULL;

	struct dirent *entry;
	while ((entry = readdir(dir)) != NULL)
	{
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
		{
			continue;
		}

		char path[PATH_MAX];
		snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);

		struct stat statbuf;
		if (stat(path, &statbuf) == -1)
		{
			continue;
		}

		if (S_ISREG(statbuf.st_mode))
		{
			if (strstr(entry->d_name, keyword) != NULL)
			{
				match = realpath(path, NULL);
				break;
			}
		}
	}

	closedir(dir);

	return match;
}

/**
 * @brief Get the absolute path object
 * 获取文件绝对路径
 * @param relative_path
 * @return char*
 */
char *get_absolute_path(const char *relative_path)
{
	char *absolute_path = realpath(relative_path, NULL);
	return absolute_path;
}

int dict_callback(void *data, int argc, char **argv, char **azColName)
{
	char *result = (char *)data;
	int i = 0;
	while (i < argc)
	{
		if (strcmp(azColName[i], "value") == 0)
		{
			sprintf(result, "%s\0", argv[i]);
		}
		i++;
	}
	return 0;
}

void get_os_name(char *osName)
{
	char result[1024] = {0};
	FILE *fp;
	fp = popen("cat /etc/os-release | grep NAME | grep -v PRETTY_NAME | grep -v DISTRO_CODENAME", "r");
	if (fp == NULL)
	{
		dzlog_error("get_os_name cmd exec error");
		return;
	}
	if (fgets(result, 100, fp) != NULL)
	{
		strcpy(osName, result);
		dzlog_info("get_os_name[%s]", osName);
	}
	pclose(fp);
}

void free_s(void *ptr)
{
	if (ptr != NULL)
	{
		free(ptr);
		ptr = NULL;
	}
}

int get_file_json(char *content, const char *filename)
{
	FILE *file = NULL;
	char *buffer = NULL;
	long file_size = 0;
	struct stat buffertemp;
	if (stat(filename, &buffertemp) == 0)
	{
		// 打开文件
		file = fopen(filename, "rb");
		if (file == NULL)
		{
			printf("无法打开文件 conf/%s\n", filename);
			return -1;
		}
		// 获取文件大小
		fseek(file, 0, SEEK_END);
		file_size = ftell(file);
		rewind(file);

		// 分配内存以存储文件内容
		buffer = (char *)malloc(sizeof(char) * (file_size + 1));
		if (buffer == NULL)
		{
			printf("内存分配失败");
			fclose(file);
			return -2;
		}

		// 读取文件内容到缓冲区
		fread(buffer, 1, file_size, file);
		buffer[file_size] = '\0';

		strcpy(content, buffer);

		// 释放内存并关闭文件
		free(buffer);
		fclose(file);
		return 0;
	}
	else
	{
		return -3;
	}
}

int toGetMemUsed(int pid, char *res)
{
	char cmd[64] = {0};
	int isreturn = -1;
	FILE *fp = NULL;
	char buffer[128];
	char buf[255];
	int i = 0;
	long Tmem = 0;
	long umem = 0;
	if ((fp = popen("cat /proc/meminfo | grep MemTotal", "r")) == NULL)
	{
		dzlog_info("toGetMemUsed start 22");
		pclose(fp);
		return -1;
	}
	// 读取输出行
	while (fgets(buffer, sizeof(buffer), fp) != NULL)
	{
		// 使用 sscanf 截取数字
		if (sscanf(buffer, "MemTotal: %ld kB", &Tmem) == 1)
		{
			break;
		}
	}
	pclose(fp);
	char dir[128] = {0};
	sprintf(dir, "/proc/%d/stat", pid);
	struct stat st = {0};
	if (stat(dir, &st) == -1)
	{
		// dzlog_info("toGetMemUsed start 55 dir[%s] not found", dir);
		return -1;
	}
	memset(cmd, 0, 64);
	sprintf(cmd, "cat /proc/%d/status | grep VmRSS", pid);
	if ((fp = popen(cmd, "r")) == NULL)
	{
		dzlog_info("toGetMemUsed start 88 cmd[%s]", cmd);
		pclose(fp);
		return -1;
	}
	// 读取输出行
	while (fgets(buffer, sizeof(buffer), fp) != NULL)
	{
		// 使用 sscanf 截取数字   VmRSS:      2912 kB
		if (sscanf(buffer, "VmRSS: %ld kB", &umem) == 1)
		{
			break;
		}
	}
	pclose(fp);
	sprintf(res, "%.2f", (double)umem / (double)Tmem * 100);


	return 0;
}

int toGetCpuUsed(int pid, char *res)
{
	char cmd[64] = {0};
	int isreturn = -1;
	FILE *fp = NULL;
	char buf[256];
	int i = 0;

	char stat_path[32];
	char buffer[1024];
	unsigned long utime, stime;
	long hertz = sysconf(_SC_CLK_TCK);

	// 读取第一次数据
	sprintf(stat_path, "/proc/%d/stat", pid);
	fp = fopen(stat_path, "r");
	if (!fp)
		return -1;

	fgets(buffer, sizeof(buffer), fp);
	sscanf(buffer, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &utime, &stime);
	unsigned long total_time1 = utime + stime;
	fclose(fp);

	// 睡眠一段时间
	sleep(1);

	// 读取第二次数据
	fp = fopen(stat_path, "r");
	if (!fp)
		return -1;

	fgets(buffer, sizeof(buffer), fp);
	sscanf(buffer, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &utime, &stime);
	unsigned long total_time2 = utime + stime;
	fclose(fp);

	// 计算CPU使用率
	double cpu_usage = ((total_time2 - total_time1) * 100.0) / (hertz * 0.5);
	sprintf(res, "%.2f", cpu_usage);


	return 0;
}

void remove_newlines(char *str) {
    if (!str) return;
    
    char *src = str;  // 源指针（读取位置）
    char *dst = str;  // 目标指针（写入位置）

    while (*src) {
        if (*src != '\r' && *src != '\n') {
            *dst++ = *src;  // 保留非换行字符
        }
        src++;
    }
    *dst = '\0';  // 添加字符串结束符
}

void remove_spaces(char *str)
{
	int i, j = 0;
	int len = strlen(str);
	for (i = 0; i < len; i++)
	{
		if (str[i] != ' ')
		{
			str[j++] = str[i];
		}
	}
	str[j] = '\0';
}

int setstatus(int status)
{
	// 没有文件，创建文件并写入
	FILE* file1 = fopen("/PowerHarmony/SMC/app/EagleEyeSMG/conf/status", "w");
	if (file1 == NULL)
	{
		return -1;
	}
	// 写入内容
	fprintf(file1, "%d", status);
	// 关闭文件
	fclose(file1);

	return 0;
}

void modify_ip(char *ip, int netmask)
{
	int octets[4];
	sscanf(ip, "%d.%d.%d.%d", &octets[0], &octets[1], &octets[2], &octets[3]);
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		if (netmask < (i + 1) * 8)
		{
			octets[i] = 0;
		}
	}

	sprintf(ip, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
}

void tosetroute()
{
	char ip_tmp[16] = {0};
	char port[16] = {0};
	char ip_route_json[16] = {0};
	char netmask[16] = {0};
	char gw[16] = {0};

	// 读取route.json
	char routePath[255] = "/PowerHarmony/SMC/Config/route.json";
	char pcJson1[255] = {0};
	memset(pcJson1, 0, 255);
	int rei = get_file_json(pcJson1, routePath);
	if (rei < 0)
	{
		return rei;
	}
	cJSON *json0 = NULL;
	json0 = cJSON_Parse(pcJson1);
	if (json0)
	{
		if (cJSON_HasObjectItem(json0, "port"))
		{
			strcpy(port, cJSON_GetObjectItem(json0, "port")->valuestring);
		}
		if (cJSON_HasObjectItem(json0, "ipAddress"))
		{
			strcpy(ip_route_json, cJSON_GetObjectItem(json0, "ipAddress")->valuestring);
		}
		if (cJSON_HasObjectItem(json0, "prefixLen"))
		{
			strcpy(netmask, cJSON_GetObjectItem(json0, "prefixLen")->valuestring);
		}
		if (cJSON_HasObjectItem(json0, "gateway"))
		{
			strcpy(gw, cJSON_GetObjectItem(json0, "gateway")->valuestring);
		}
	}
	cJSON_Delete(json0);
	if (strlen(port) == 0)
	{
		strcpy(port, "ppp0");
	}
	modify_ip(ip_route_json, atoi(netmask));
	if (netmask != NULL && strlen(netmask) != 0)
	{
		if (atoi(netmask) <= 8)
		{
			sprintf(netmask, "8");
		}
		else if (atoi(netmask) > 8 && atoi(netmask) <= 16)
		{
			sprintf(netmask, "16");
		}
		else if (atoi(netmask) > 16 && atoi(netmask) <= 24)
		{
			sprintf(netmask, "24");
		}
		else
		{
			sprintf(netmask, "32");
		}
	}
	char setroute[255] = {0};
	
	if (ip_route_json != NULL || strlen(ip_route_json) != 0)
	{
		memset(setroute, 0, 255);
		if (gw != NULL || strlen(gw) != 0)
		{
			sprintf(setroute, "ip route add %s/%s via %s dev %s", ip_route_json, netmask, gw, port);
		}
		else
		{
			sprintf(setroute, "ip route add %s/%s dev %s", ip_route_json, netmask, port);
		}

		strcat(setroute, " > /dev/null 2> error.log");
		// printf(setroute);
		// printf("\n");
		system(setroute);
	}
	printf("1");
	return;
}

void togettime_ym(char *date_ym)
{
	time_t current_time = time(NULL);
	if (current_time == -1)
	{
		perror("Failed to get current time");
		return 1;
	}

	struct tm *time_info = localtime(&current_time);
	if (time_info == NULL)
	{
		perror("Failed to convert time");
		return 1;
	}

	int year = time_info->tm_year + 1900;
	int month = time_info->tm_mon + 1;

	sprintf(date_ym, "%04d%02d", year, month);
	return;
}

int popen_get_json(char **json_string, const char *cmd)
{
	char buf[256] = {0};
	FILE *fp = NULL;
	size_t len = 0;
	*json_string = NULL; // 初始化为NULL，以便在需要时分配内存

	if ((fp = popen(cmd, "r")) == NULL)
	{
		perror("popen");
		return -1;
	}
	// 初始分配内存
	*json_string = malloc(1);
	if (*json_string == NULL)
	{
		perror("malloc");
		pclose(fp);
		return -1;
	}
	**json_string = '\0'; // 初始化为空字符串
						  // 读取result到内存中
	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		// 为新的字符串内容分配内存（包括之前的内容和新的行）
		char *temp = realloc(*json_string, len + strlen(buf) + 1);
		if (temp == NULL)
		{
			perror("realloc");
			pclose(fp);
			free(*json_string); // 释放之前分配的内存
			*json_string == NULL;
			return -1;
		}
		*json_string = temp;
		strcat(*json_string, buf);
		len += strlen(buf);
	}
	// 去掉可能的换行符（如果 JSON 文件不是单行的话）
	if (len > 0 && (*json_string)[len - 1] == '\n')
	{
		(*json_string)[len - 1] = '\0';
	}
	// dzlog_info("%s:%s",cmd,*json_string);
	pclose(fp);

	return 0;
}

void generate_random_string(char *str, size_t length) { 
    const char charset[] = "0123456789"
                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                           "abcdefghijklmnopqrstuvwxyz";
    
    // // 设置随机种子
    // srand(time(NULL));

    for (size_t i = 0; i < length-1; i++) {
        int index = rand() % (sizeof(charset) - 1);
        str[i] = charset[index];
    }
    str[length-1] = '\0'; // 字符串结尾
}

/**
 * @brief 判断字符串是否纯ASCII，若否则转换非ASCII字符
 * @param input   输入字符串
 * @param mode    转换模式：0-移除非ASCII，1-替换为'?'，2-转义为\xHH
 * @return char*  转换后的字符串（需调用者释放内存）
 */
void convert_to_ascii(const char* input, char* output, int mode)
{
	if (!input)
		return NULL;

	// 计算输出字符串最大可能长度
	size_t in_len = strlen(input);
	size_t out_len = (mode == 2) ? in_len * 4 : in_len + 1;
	//char* output = malloc(out_len);
	if (!output)
		return NULL;

	size_t j = 0;
	for (size_t i = 0; i < in_len; ++i)
	{
		unsigned char c = input[i];
		if (c <= 127)
		{ // ASCII字符直接保留
			output[j++] = c;
		}
		else
		{ // 非ASCII字符处理
			switch (mode)
			{
			case 0: // 模式0：直接移除
				break;
			case 1: // 模式1：替换为'?'
				output[j++] = '?';
				break;
			case 2: // 模式2：转义为\xHH形式（如\xA3）
				snprintf(output + j, 4, "\\x%02X", c);
				j += 4;
				break;
			default: // 无效模式视为模式0
				break;
			}
		}
	}
	output[j] = '\0'; // 终止符

	//// 优化内存：按实际长度重新分配
	//char* final = realloc(output, j + 1);
	//return final ? final : output;
	return;
}

int split_string(char* input, char tmp[4][6]) {
	char* token;
	int i = 0;
	token = strtok(input, "|");
	while (token != NULL && i < 4) {
		if (token != NULL && strlen(token) != 0)
		{
			dzlog_info("i[%d],token[%s]",i, token);
			strncpy(tmp[i], token, 5);
			tmp[i][5] = '\0';
			i++;
		}
		token = strtok(NULL, "|");
	}
	return i;
}

void move_matched_connection_to_front(cJSON* root, const char* target_ip) {

	cJSON* connections = cJSON_GetObjectItemCaseSensitive(root, "connections");
	if (!connections || !cJSON_IsArray(connections)) return;
	cJSON* matched = NULL;
	cJSON* item = NULL;

	// 查找匹配的IP
	cJSON_ArrayForEach(item, connections) {
		cJSON* ip = cJSON_GetObjectItem(item, "ip");
		if (ip && cJSON_IsString(ip) && strcmp(ip->valuestring, target_ip) == 0) {
			matched = item;
			break;
		}
	}
	if (matched) {
		// 创建新数组并调整顺序
		cJSON* new_array = cJSON_CreateArray();
		cJSON_AddItemToArray(new_array, cJSON_Duplicate(matched, 1));  // 复制匹配项到首位

		// 添加其他元素（跳过匹配项）
		cJSON_ArrayForEach(item, connections) {
			if (item != matched) {
				cJSON_AddItemToArray(new_array, cJSON_Duplicate(item, 1));
			}
		}

		// 直接替换根对象中的connections数组
		cJSON_ReplaceItemInObject(root, "connections", new_array);
	}
}

//雪花算法//////
// 获取当前毫秒时间戳
uint64_t current_timestamp() {
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (uint64_t)(tv.tv_sec) * 1000 + (uint64_t)(tv.tv_usec) / 1000;
}

// 初始化雪花算法结构
int snowflake_init(Snowflake* sf, uint64_t worker_id) {
	if (worker_id > MAX_WORKER_ID) {
		return -1;  // 无效的worker_id
	}

	sf->last_timestamp = 0;
	sf->worker_id = worker_id;
	sf->sequence = 0;
	pthread_mutex_init(&sf->mutex, NULL);
	return 0;
}

// 生成唯一ID
uint64_t snowflake_next_id(Snowflake* sf) {
	pthread_mutex_lock(&sf->mutex);

	uint64_t timestamp = current_timestamp();

	// 处理时钟回拨
	if (timestamp < sf->last_timestamp) {
		// 简单处理：等待时钟追上
		while (timestamp < sf->last_timestamp) {
			usleep(1000);  // 休眠1毫秒
			timestamp = current_timestamp();
		}
	}

	// 同一毫秒内的序列处理
	if (timestamp == sf->last_timestamp) {
		sf->sequence = (sf->sequence + 1) & MAX_SEQUENCE;
		if (sf->sequence == 0) {
			// 当前毫秒序列号用完，等待下一毫秒
			while (timestamp <= sf->last_timestamp) {
				usleep(1000);
				timestamp = current_timestamp();
			}
		}
	}
	else {
		sf->sequence = 0;  // 新毫秒重置序列
	}

	sf->last_timestamp = timestamp;

	// 组合ID
	uint64_t id = ((timestamp - EPOCH) << (WORKER_ID_BITS + SEQUENCE_BITS))
		| (sf->worker_id << SEQUENCE_BITS)
		| sf->sequence;

	pthread_mutex_unlock(&sf->mutex);
	return id;
}

// 清理资源
void snowflake_cleanup(Snowflake* sf) 
{
	pthread_mutex_destroy(&sf->mutex); 
}

uint64_t getSnowflakeId(char * output_id)
{
	uint64_t id = snowflake_next_id(&sf);
	printf("Generated ID: %lu\n", id);
	snprintf(output_id, 37, "%lu", id);
	//snowflake_cleanup(&sf);
	return id;
}

//雪花算法end//////////////

double convert_string_to_double(const char* input) {
	// 步骤1: 创建可修改的字符串副本
	char* buffer = strdup(input);
	if (!buffer) {
		perror("内存分配失败");
		return 0.0;
	}

	// 步骤2: 去除所有百分号
	char* read_ptr = buffer;
	char* write_ptr = buffer;

	while (*read_ptr) {
		if (*read_ptr != '%') {
			*write_ptr = *read_ptr;
			write_ptr++;
		}
		read_ptr++;
	}
	*write_ptr = '\0';  // 添加字符串终止符

	// 步骤3: 去除前后空格
	// 跳过前导空格
	char* start = buffer;
	while (isspace((unsigned char)*start)) start++;

	// 处理后置空格
	char* end = start + strlen(start) - 1;
	while (end > start && isspace((unsigned char)*end)) end--;
	*(end + 1) = '\0';

	// 步骤4: 转换为double
	char* endptr;
	double result = strtod(start, &endptr);

	// 步骤5: 检查转换是否成功
	if (endptr == start) {
		fprintf(stderr, "错误: 无法转换字符串 '%s'\n", input);
		result = 0.0;  // 或者返回错误代码
	}
	else if (*endptr != '\0') {
		fprintf(stderr, "警告: 字符串 '%s' 包含额外字符 '%s'\n", input, endptr);
	}

	// 清理内存
	free(buffer);
	return result;
}

/**
 * 检测指定IP和端口的网络连通性
 *
 * @param ip 目标IP地址 (字符串格式，如 "192.168.1.100")
 * @param port 目标端口号
 * @param timeout_sec 超时时间(秒)
 *
 * @return 连接成功返回0，失败返回错误代码:
 *   -1: 参数错误
 *   -2: 创建socket失败
 *   -3: 设置非阻塞失败
 *   -4: 连接失败
 *   -5: 连接超时
 *   -6: 其他错误
 */
int check_connectivity(const char* ip, int port, int timeout_sec) {
	// 参数校验
	if (!ip || port <= 0 || port > 65535 || timeout_sec <= 0) {
		return -1;
	}

	// 创建TCP socket
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		return -2;
	}

	// 设置非阻塞模式
	int flags = fcntl(sock, F_GETFL, 0);
	if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
		close(sock);
		return -3;
	}

	// 设置目标地址
	struct sockaddr_in addr = {
		.sin_family = AF_INET,
		.sin_port = htons(port)
	};

	// 转换IP地址
	if (inet_pton(AF_INET, ip, &addr.sin_addr) <= 0) {
		close(sock);
		return -1; // 无效的IP地址
	}

	// 发起非阻塞连接
	int rc = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
	if (rc == 0) {
		// 立即连接成功（本地连接可能）
		close(sock);
		return 0;
	}

	// 检查错误类型
	if (errno != EINPROGRESS) {
		close(sock);
		return -4;
	}

	// 使用select等待连接完成
	fd_set writefds;
	FD_ZERO(&writefds);
	FD_SET(sock, &writefds);

	struct timeval timeout = {
		.tv_sec = timeout_sec,
		.tv_usec = 0
	};

	rc = select(sock + 1, NULL, &writefds, NULL, &timeout);
	if (rc == 0) {
		// 超时
		close(sock);
		return -5;
	}
	else if (rc < 0) {
		// select错误
		close(sock);
		return -6;
	}

	// 检查socket是否真的连接成功
	int error = 0;
	socklen_t len = sizeof(error);
	if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
		close(sock);
		return -6;
	}

	close(sock);
	return (error == 0) ? 0 : -4;
}

// 检查文件是否存在
int file_exists_v1(const char* filename) {
	struct stat buffer;
	return (stat(filename, &buffer) == 0);
}

// 获取文件修改时间
time_t get_file_mod_time(const char* filename) {
	struct stat attr;
	if (stat(filename, &attr) == 0) {
		return attr.st_mtime;
	}
	return -1;
}

int set_iot_info_v1(int iotTlsCurrent)
{
	cJSON* json = NULL;
	char* fileName = "./conf/iotInfo.json";
	char tmp[8] = { 0 };
	sprintf(tmp, "%d", iotTlsCurrent);
	struct stat buffer;
	if (!stat(fileName, &buffer) == 0) 
	{
		printf("文件不存在: %s\n", fileName);
		json = cJSON_CreateObject();
		cJSON_AddStringToObject(json, "iotTlsCurrent", tmp);
	}
	else
	{
		char pcJson[512] = { 0 };
		int re = get_file_json(pcJson, fileName);
		cJSON* json1 = NULL;
		json = cJSON_Parse(pcJson);
		if (json)
		{
			if (cJSON_HasObjectItem(json, "iotTlsCurrent"))
			{
				cJSON_ReplaceItemInObject(json, "iotTlsCurrent", cJSON_CreateString(tmp));
			}
			else
			{
				cJSON_AddStringToObject(json, "iotTlsCurrent", tmp);
			}
		}
	}
	dzlog_error("set_iot_info_v1 iotTlsCurrent[%d]", iotTlsCurrent);
	// 将修改后的JSON写回文件
	char* output = cJSON_Print(json);
	FILE* file = fopen(fileName, "w");
	if (file == NULL)
	{
		cJSON_Delete(json);
		free(output);
		printf("0");
		return -1;
	}
	fwrite(output, 1, strlen(output), file);

	fclose(file);
	cJSON_Delete(json);
	free(output);
	system("chmod 777 ./conf/iotInfo.json");
	return 0;
}
